import HeartCheckUtil from '@/utils/websocket/heartCheck'

export default class WebsocketUtil {
  // 避免ws重复连接
  lockReconnect = false
  // websocket 实例
  ws
  // 建立socket连接的url
  socketUrl
  // 心跳检查实例
  heartCheckUtil
  // 过多长时间重新连接
  reconnectIntervalTime = 1000
  // 是否打印日志
  isShowLog = true

  constructor ({socketUrl, reconnectIntervalTime, onclose, onerror, onopen, onmessage}) {
    this.socketUrl = socketUrl
    this.onclose = onclose || (() => {})
    this.onerror = onerror || (() => {})
    this.onopen = onopen || (() => {})
    this.onmessage = onmessage || (() => {})
    this.reconnectIntervalTime = reconnectIntervalTime || this.reconnectIntervalTime
    this.heartCheckUtil = new HeartCheckUtil()
    this.createWebSocket()
  }

  /**
   * @func createWebSocket
   * @desc 创建 websocket 对象
   * @param {object} options - 行过滤器的可见信息
   */
  createWebSocket () {
    try {
      if ('WebSocket' in window) {
        this.ws = new WebSocket(this.socketUrl)
      }
      this.initEventHandle()
    } catch (e) {
      this.reconnect();
      this.isShowLog && console.log(e);
    }
  }

  /**
   * @func initEventHandle
   * @desc 监听 socket 事件
   * @param {object} options - 行过滤器的可见信息
   */
  initEventHandle () {
    this.ws.onclose = () => {
      this.onclose()
      this.reconnect()
      this.isShowLog && console.log("llws连接关闭!"+new Date().toLocaleString())
    }
    this.ws.onerror = () => {
      this.onerror()
      this.reconnect()
      this.isShowLog && console.log("llws连接错误!")
    }
    this.ws.onopen = () => {
      this.onopen()
      //心跳检测重置
      this.heartCheckUtil.reset().start(this.ws)
      this.isShowLog && console.log(`llws连接成功!${new Date().toLocaleString()}`)
    }
    this.ws.onmessage = (event) => {    //如果获取到消息，心跳检测重置
      this.heartCheckUtil.reset().start(this.ws)     //拿到任何消息都说明当前连接是正常的
      this.isShowLog && console.log(`llws收到消息啦:${event.data}`)
      if (event.data !== 'pong') {
        let data = JSON.parse(event.data)
        this.isShowLog && console.log(data)
        this.onmessage(data)
      }
    }
  }

  /**
   * @func reconnect
   * @desc 重新建立连接
   * @param {object} options - 行过滤器的可见信息
   */
  reconnect () {
    if (this.lockReconnect) {
      return false
    }
    this.lockReconnect = true;
    // 没连接上会一直重连，设置延迟避免请求过多
    setTimeout(() => {
      this.createWebSocket()
      this.lockReconnect = false
    }, this.reconnectIntervalTime)
  }
  
  /**
   * @func reconnect
   * @desc 重新建立连接
   * @param {object} options - 行过滤器的可见信息
   */
  close () {
    this.ws.close()
  }
}
